# %%
from functools import reduce

a = [1, 2, 3, 4, 5, 6, 8]
b = [i ** i + 2 for i in a]
print('a:', a)
print('b:', b)
# %% 行函数，类似matlab的匿名函数
c = 6
e = list(range(1, 8))
d = reduce(lambda x, y: x * y, range(1, c + 1))
print(d)

# %%
# -*- coding: utf-8 -*
# 求解非线性方程组2x1-x2^2=1,x1^2-x2=2
# 导入求解方程组的函数
from scipy.optimize import fsolve


def f(x):  # 定义要求解的方程组
    x1 = x[0]
    x2 = x[1]
    return [2 * x1 - x2 ** 2 - 1, x1 ** 2 - x2 - 2]


result = fsolve(f, [1, 1])  # 输入初值[1, 1]并求解
print(result) # 输出结果，为array([ 1.91963957,  1.68501606])

# 数值积分
from scipy import integrate  # 导入积分函数


def g(x):  # 定义被积函数
    return (1 - x ** 2) ** 0.5


pi_2, err = integrate.quad(g, -1, 1)  # 积分结果和误差
print(pi_2 * 2)  # 由微积分知识知道积分结果为圆周率pi的一半

# %% 创建字典
dic_1 = {'today': 20, 'tomorrow': 11}

# dict可以批量快捷创建字典
# dic_2 = dict([['today', 20], ['tomorrow', 22]])
print(dic_1['today'])

# %% 创建集合
S = {1, 2, 2, 3, 4, 5}  # 直接创建集合，因为不重复性，2会直接过滤掉
print(S)
S_set = set([1, 2, 3, 4, 5, 5, 6, 6, 7])
print(S_set)

# %% numpy库
import numpy as np

np_1 = np.array([[list(range(1, 4))], [list(range(5, 9))]])
# print(np_1)

np_2 = np.array([[1, 2, 3, 4], [2, 3, 4, 5]])
# print(np_2)

# %% StatsModels ADF平稳性检验
from statsmodels.tsa.stattools import adfuller as ADF
import numpy as np

ADF(np.random.rand(100))

# %% scikit-Learn 线性回归模型
from sklearn.linear_model import LogisticRegression  # 导入线性回归模型

model = LogisticRegression()  # 建立线性回归模型
print(model)

# %% 导入训练训练数据‘
from sklearn import datasets

iris = datasets.load_iris()
print(iris.data.shape)

# %% 导入keras库
'''
from keras.models import Sequential
from keras.layers.core import Dense, Dropout, Activation
from keras.optimizers import SGD

model = Sequential()  # 模型初始化
model.add(Dense(20, 64))  # 添加输入层（20个节点），第一隐藏层（64个节点）的连接
model.add(Activation('tanh'))  # 第一隐藏层用‘tanh’作为激活函数
model.add(Dropout(0.5))  # 使用Dropout防止过拟合
model.add(Dense(64, 64))  # 添加第一隐藏层（64个节点），第二隐藏层（64个节点）的连接
model.add(Activation('tanh'))  # 第二隐藏层用‘tanh’作为激活函数
model.add(Dropout(0.5))  # 使用Dropout防止过拟合
model.add(Dense(64, 1))  # 添加第二隐藏层（64个节点），输出层（1个节点）的连接
model.add(Activation('sigmoid'))  # 输出层使用‘sigmoid’作为激活函数

sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)  # 定义求解算法
model.compile(loss='mean_squared_error', optimizer=sgd)  # 编辑生成模型，损失函数为平均误差平方和

# model.fit(X_train, y_train, nb_epoch=20, batch_size=16)  # 训练数据
# scor = model.evaluate(X_test, y_test, batch_size=16)  # 测试数据
'''

# %%异常值分析
import pandas as pd

catering_sale = 'data//catering_sale.xls'  # 餐饮数据
data = pd.read_excel(catering_sale, index_col=u'日期')  # 读取数据，指定“日期”列为索引列

import matplotlib.pyplot as plt  # 导入图像库

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

plt.figure()  # 建立图像
p = data.boxplot(return_type='dict')  # 画箱线图，直接使用DataFrame的方法
x = p['fliers'][0].get_xdata()  # 'fliers'即为异常值的标签
y = p['fliers'][0].get_ydata()
y.sort()  # 从小到大排序，该方法直接改变原对象

# 用annotate添加注释
# 其中有些相近的点，注解会出现重叠，难以看清，需要一些技巧来控制。
# 以下参数都是经过调试的，需要具体问题具体调试。
for i in range(len(x)):
    if i > 0:
        plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.05 - 0.8 / (y[i] - y[i - 1]), y[i]))
    else:
        plt.annotate(y[i], xy=(x[i], y[i]), xytext=(x[i] + 0.08, y[i]))

plt.show()  # 展示箱线图

# %% 餐饮销数据统计量分析

import pandas as pd

catering_sale = 'data//catering_sale.xls'  # 餐饮数据
data_1 = pd.read_excel(catering_sale, index_col=u'日期')
data_1 = data_1[(data_1['销量'] > 400) & (data_1['销量'] < 5000)]
statistics = data_1.describe()

statistics.loc['range'] = statistics.loc['max'] - statistics.loc['min']  # 极差
statistics.loc['var'] = statistics.loc['std'] - statistics.loc['mean']  # 变异系数
statistics.loc['dis'] = statistics.loc['75%'] - statistics.loc['25%']  # 四分位间距

print(statistics)

# %% 餐饮行业销量数据相关性分析
import pandas as pd

catering_sale = catering_sale = 'data//catering_sale_all.xls'  # 餐饮数据
data_2 = pd.read_excel(catering_sale, index_col=u'日期')

data_2.corr()  # 相关系数矩阵，即给出了任意两款菜式之间的相关系数
data_2.corr()[u'百合酱蒸凤爪']  # 只显示百合酱蒸凤爪与其他菜式的相关系数
data_2[u'百合酱蒸凤爪'].corr(data_2[u'翡翠蒸香茜饺'])  # 计算百合酱蒸凤爪和翡翠蒸香犀角

# %% 测试提取单列或者多列
import numpy as np
import pandas as pd

D = pd.DataFrame(np.random.randn(6, 5))  # 创建六行五列的随机矩阵
print(D)
s1 = D.loc[0]  # 提取第1行
s2 = D.loc[1]

s3 = D[0]
s4 = D[1]
print(s1)
print(s2)
print(s3)
print(s4)

# %% 拉格朗日中值进行补插
import pandas as pd
from scipy.interpolate import lagrange

inputfile = 'data//catering_sale.xls'
outputfile = 'data//out_sales.xls'

data_3 = pd.read_excel(inputfile)
# data_3[u'销量'][(data_3[u'销量'] < 400) | (data_3[u'销量'] > 5000)] = None  # 过滤异常值，将其变为空值
data_3.loc[(data_3[u'销量'] < 400) | (data_3[u'销量'] > 5000), u'销量'] = None  # 过滤异常值，将其变为空值


# 自定义列向量插值函数
# s为列向量，n为被插值的位置，k为取前后数据的个数，默认是5
def ployinterp_column(s, n, k=5):
    yy = s[list(range(n - k)) + list(range(n + 1, n + 1 + k))]  # 取数
    yy = yy[yy.notnull()]  # 剔除空值
    return lagrange(yy.index, list(yy))(n)  # 插值并返回插值结果


# 逐个元素是否需要插值
for i in data_3.columns:
    for j in range(len(data_3)):
        if (data_3[i].isnull())[j]:
            data_3[i][j] = ployinterp_column(data_3[i], j)

data_3.to_excel(outputfile)  # 输出结果，写入文件

# %% PCA主成分分析降维
import pandas as pd
import heapq

# 参数初始化
inputfile1 = 'data//principal_component.xls'
outputfile1 = 'data//out_simention_reducted.xls'

data_4 = pd.read_excel(inputfile1)  # 读取数据

from sklearn.decomposition import PCA

pca = PCA()
pca.fit(data_4)
print('返回各个特征向量\n', pca.components_)  # 返回模型的各个特征向量
print('返回各个成分各自的占比\n', pca.explained_variance_ratio_)  # 返回各个成分各自的方差占比

pca = PCA(3)  # 设置降维模型为3维
pca.fit(data_4)
low_d = pca.transform(data_4)
pd.DataFrame(low_d).to_excel(outputfile1)  # 保存结果

'''
必要时可以使用inverse_transform()函数复原数据
pca.inverse_transform(low_d)
'''
